package com.tanxi521.afkreward.data;

import com.tanxi521.afkreward.AfkReward;
import com.tanxi521.afkreward.pojo.PlayerAfk;
import com.tanxi521.tnlevel.dao.ConnectionPool;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class AFKRewardMapper {

    public static final ConcurrentHashMap<String, PlayerAfk> AFK_MAP = new ConcurrentHashMap<>();

    public static void createTable() {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.createTable());
            statement.execute();
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l初始化数据失败");
        } finally {
            try {
                if (statement != null) statement.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void insertPlayer(PlayerAfk player) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.initPlayer());
            statement.setString(1, player.getPlayerName());
            statement.setString(2, player.getPlayerUuid());
            statement.setString(3, player.getType());
            statement.setString(4, player.getReward());
            statement.setLong(5, player.getStart());
            statement.setLong(6, player.getEnd());
            statement.setLong(7, player.getTotal());
            statement.setLong(8, player.getTimes());
            statement.setLong(9, 0L);
            statement.setString(10, player.getPlayerName());
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l初始化玩家数据失败");
        } finally {
            try {
                if (statement != null) statement.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static int getRest(String playerName) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.getRest());
            statement.setString(1, playerName);
            rs = statement.executeQuery();
            int rest = 0;
            while (rs.next()) rest = rs.getInt(1);
            return rest;
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l获取玩家剩余挂机次数失败");
            return 0;
        } finally {
            try {
                if (statement != null) statement.close();
                if (rs != null) rs.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void startAfk(PlayerAfk playerAfk) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.startAfk());
            statement.setLong(1, playerAfk.getStart());
            statement.setLong(2, playerAfk.getEnd());
            statement.setString(3, playerAfk.getType());
            statement.setString(4, playerAfk.getReward());
            statement.setString(5, playerAfk.getPlayerName());
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l设置玩家信息失败");
        } finally {
            try {
                if (statement != null) statement.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static boolean isAfk(String playerName) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.isAfk());
            statement.setString(1, playerName);
            rs = statement.executeQuery();
            int count = 0;
            while (rs.next()) count = rs.getInt(1);
            return count > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l检查玩家当前状态失败");
            return false;
        } finally {
            try {
                if (statement != null) statement.close();
                if (rs != null) rs.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static PlayerAfk getPlayerInfo(String playerName) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        ResultSet rs = null;
        PlayerAfk playerAfk = new PlayerAfk();
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.getPlayerInfo());
            statement.setString(1, playerName);
            rs = statement.executeQuery();
            rs.next();
            playerAfk.setPlayerUuid(rs.getString("player_uuid"));
            playerAfk.setPlayerName(rs.getString("player_name"));
            playerAfk.setType(rs.getString("type"));
            playerAfk.setReward(rs.getString("reward"));
            playerAfk.setStart(rs.getLong("start"));
            playerAfk.setEnd(rs.getLong("end"));
            playerAfk.setTimes(rs.getLong("times"));
            playerAfk.setTotal(rs.getLong("total"));
            playerAfk.setToday(rs.getLong("today"));
            return playerAfk;
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l获取玩家信息失败");
            return null;
        } finally {
            try {
                if (statement != null) statement.close();
                if (rs != null) rs.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static List<PlayerAfk> getAfkPlayerList(int start, int size) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.getAfkPlayerList());
            statement.setInt(1, start);
            statement.setInt(2, size);
            rs = statement.executeQuery();
            List<PlayerAfk> playerAfks = new ArrayList<>();
            while (rs.next()) {
                PlayerAfk playerAfk = new PlayerAfk();
                playerAfk.setPlayerUuid(rs.getString("player_uuid"));
                playerAfk.setPlayerName(rs.getString("player_name"));
                playerAfk.setType(rs.getString("type"));
                playerAfk.setReward(rs.getString("reward"));
                playerAfk.setStart(rs.getLong("start"));
                playerAfk.setEnd(rs.getLong("end"));
                playerAfk.setTimes(rs.getLong("times"));
                playerAfk.setTotal(rs.getLong("total"));
                playerAfk.setToday(rs.getLong("today"));
                playerAfks.add(playerAfk);
            }
            return playerAfks;
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l获取玩家信息失败");
            return null;
        } finally {
            try {
                if (statement != null) statement.close();
                if (rs != null) rs.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void updatePlayer(PlayerAfk playerAfk) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.updatePlayer());
            statement.setString(1, playerAfk.getType());
            statement.setString(2, playerAfk.getReward());
            statement.setLong(3, playerAfk.getStart());
            statement.setLong(4, playerAfk.getEnd());
            statement.setLong(5, playerAfk.getTotal());
            statement.setLong(6, playerAfk.getTimes());
            statement.setLong(7, playerAfk.getToday());
            statement.setString(8, playerAfk.getPlayerName());
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l更新玩家信息失败");
        } finally {
            try {
                if (statement != null) statement.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void updateOfflinePlayerEnd() {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.setOfflineEnd());
            statement.setLong(1, System.currentTimeMillis());
            statement.executeUpdate();
            AfkReward.getInstance().getLogger().info("§e离线玩家数据更新完成");
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l离线玩家数据更新失败");
        } finally {
            try {
                if (statement != null) statement.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void updateExitPlayerEnd(String playerName) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.playerExitUpdate());
            statement.setLong(1, System.currentTimeMillis());
            statement.setString(2, playerName);
            int i = statement.executeUpdate();
            if (i > 0) {
                AfkReward.getInstance().getLogger().warning("§e玩家 " + playerName + " 意外离线，已更新离线时间为挂机结束时间");
            }
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l离线玩家数据更新失败");
        } finally {
            try {
                if (statement != null) statement.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static List<PlayerAfk> getAfkTop(int start, int size) {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.getAfkTop());
            statement.setInt(1, start);
            statement.setInt(2, size);
            rs = statement.executeQuery();
            List<PlayerAfk> playerAfks = new ArrayList<>();
            while (rs.next()) {
                PlayerAfk playerAfk = new PlayerAfk();
                playerAfk.setPlayerUuid(rs.getString("player_uuid"));
                playerAfk.setPlayerName(rs.getString("player_name"));
                playerAfk.setType(rs.getString("type"));
                playerAfk.setReward(rs.getString("reward"));
                playerAfk.setStart(rs.getLong("start"));
                playerAfk.setEnd(rs.getLong("end"));
                playerAfk.setTimes(rs.getLong("times"));
                playerAfk.setTotal(rs.getLong("total"));
                playerAfk.setToday(rs.getLong("today"));
                playerAfks.add(playerAfk);
            }
            return playerAfks;
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l获取玩家信息失败");
            return null;
        } finally {
            try {
                if (statement != null) statement.close();
                if (rs != null) rs.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static int getAfkCount() {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.getAfkPlayerCount());
            rs = statement.executeQuery();
            int rest = 0;
            while (rs.next()) rest = rs.getInt(1);
            return rest;
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l获取挂机玩家数量失败");
            return 0;
        } finally {
            try {
                if (statement != null) statement.close();
                if (rs != null) rs.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static int getAllCount() {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.getAllCount());
            rs = statement.executeQuery();
            int rest = 0;
            while (rs.next()) rest = rs.getInt(1);
            return rest;
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l获取玩家数量失败");
            return 0;
        } finally {
            try {
                if (statement != null) statement.close();
                if (rs != null) rs.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void updateToday() {
        Connection connection = ConnectionPool.getConnection();
        PreparedStatement statement = null;
        try {
            assert connection != null;
            statement = connection.prepareStatement(SQLStatement.updateToday());
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l玩家数据更新失败");
        } finally {
            try {
                if (statement != null) statement.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static int compute(String sql) {
        Connection connection = ConnectionPool.getConnection();
        Statement statement = null;
        ResultSet rs = null;
        try {
            assert connection != null;
            statement = connection.createStatement();
            rs = statement.executeQuery("select " + sql);
            int res = 0;
            while (rs.next()) res = rs.getInt(1);
            return res;
        } catch (SQLException e) {
            e.printStackTrace();
            AfkReward.getInstance().getLogger().warning("§c§l奖励指令计算失败，请检查指令格式");
            return 0;
        } finally {
            try {
                if (statement != null) statement.close();
                if (rs != null) rs.close();
                ConnectionPool.returnSource(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    }
}
